import createDOMString from '../../utils/createDOMString';
import { inRange, toNumOrDefault } from '../../utils/number';
import { noStar, stared } from './icon';
import createElement from '../../utils/createElement';

function halfRate(raw, max, half = false) {
  raw = inRange(toNumOrDefault(raw, 0), 0, max);
  if (!half) {
    return Math.round(raw);
  }
  raw = raw * 10;
  let more = raw % 5;
  if (more === 0) {
    return raw / 10;
  } else {
    const less = Math.floor(raw / 5);
    more = more >= 3 ? 5 : 0;
    return (less * 5 + more) / 10;
  }
}

function renderItems(num, item) {
  const res = [];
  for (let i = 0; i < num; i++) {
    res.push(`<div class="rate-item" index="${i}">${item}</div>`);
  }
  return res.join('');
}

function getRateItem(item) {
  while (item.className !== 'rate-item') {
    item = item.parentElement;
  }
  return item;
}

function checkRate(item, event, half = false) {
  if (half) {
    const left = item.getBoundingClientRect().left + item.offsetWidth / 2;
    return left <= event.x ? 1 : 0.5;
  } else {
    return 1;
  }
}

createElement({
  name: 'cms-rate',
  props: {
    value: (cur, { max, half }) => {
      console.log('rate value === ', cur);
      return halfRate(cur, max, half);
    },
    max: cur => {
      let res = Math.round(toNumOrDefault(cur, 5));
      return res <= 0 ? 5 : res;
    },
    half: (cur, { max, value }, target) => {
      const res = cur !== null && cur !== 'false';
      target.value = halfRate(value, max, res);
      return res;
    },
  },
  defaultProps: {
    value: 0,
    max: 5,
    half: false,
  },
  events: (target, addEvent, dispatch) => {
    const starContent = target.shadowRoot.querySelector('.star-content');
    function handleMouseOver(e) {
      const item = getRateItem(e.target);
      const res = +item.getAttribute('index') + checkRate(item, e, target.half);
      starContent.style.setProperty('--show', res);
    }
    addEvent('.no-star-content', 'mouseover', handleMouseOver);
    addEvent('.star-content', 'mouseover', handleMouseOver);
    addEvent(target, 'click', () => {
      target.value = +starContent.style.getPropertyCSSValue('--show').cssText;
      dispatch('rate', target.value);
    });
    addEvent(target, 'mouseleave', () => {
      target.shadowRoot.querySelector('.star-content').classList.remove('hover');
      starContent.style.setProperty('--show', target.value);
    });
  },
  render(props) {
    return createDOMString(props)`
      <style>
        :host: {
          --edge: 30px;
        }
        :host {
          position: relative;
          display: inline-block;
          box-sizing: border-box;
          height: var(--edge, 30px);
          user-selector: none;
          overflow: hidden;
        }
        :host .rate-item {
          display: inline-block;
          width: var(--edge, 30px);
          height: var(--edge, 30px);
          cursor: pointer;
          position: relative;
        }
        :host .rate-item svg {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          width: var(--edge, 30px);
          height: var(--edge, 30px);
        }
        :host .star-content  {
          white-space: nowrap;
          width: calc(var(--show, ${props => props.value}) / ${props.max} * 100%);
          position: absolute;
          z-index: 1;
          left: 0;
          top: 0;
          overflow: hidden;
        }
      </style>
      <div class="no-star-content">
        ${props => renderItems(props.max, noStar)}
      </div>
      <div class="star-content">
        ${props => renderItems(props.max, stared)}
      </div>
    `;
  },
});
